/**
 * 并发执行异步任务，并限制同时执行的任务数量。
 * @param {Array<Function>} tasks 异步任务数组，每个任务都是一个返回 Promise 的函数。
 * @param {number} limit 同时执行的任务数量限制。
 * @returns {Promise<Array>} 所有任务完成后的结果数组，包含所有任务执行后的结果或错误。
 */
function concurrencyLimit(tasks, limit) {
  // TODO：待补充代码
  return new Promise((resolve, reject) => {
    let results = []; // 存储所有任务的结果或错误
    let index = 0; // 当前执行的任务索引
    let running = 0; // 当前正在运行的任务数量
    /**
     * 执行单个任务，并将其结果或错误推入结果数组中。
     * @param {Function} task 要执行的任务函数。
     */
    function runTask(task) {
      running++; // 增加正在运行的任务数量
      task() // 执行任务，返回一个 Promise
        .then(
          (result) => {
            // 如果任务成功完成
            results.push(result); // 将任务结果推入结果数组中
            running--; // 减少正在运行的任务数量
            if (index < tasks.length) {
              // 如果还有未执行的任务
              runTask(tasks[index++]); // 执行下一个任务
            } else if (running === 0) {
              // 如果没有正在运行的任务
              resolve(results); // 所有任务都完成了，解决 Promise 并返回结果数组
            }
          },
          (error) => {
            // 如果任务执行失败
            results.push(error); // 将任务错误信息推入结果数组中
            running--; // 减少正在运行的任务数量
            if (index < tasks.length) {
              // 如果还有未执行的任务
              runTask(tasks[index++]); // 执行下一个任务
            } else if (running === 0) {
              // 如果没有正在运行的任务
              resolve(results); // 所有任务都完成了，解决 Promise 并返回结果数组
            }
          }
        );
    }

    // 最多同时执行 limit 个任务，但不超过任务数组的长度
    for (let i = 0; i < limit && i < tasks.length; i++) {
      runTask(tasks[index++]); // 执行第 i 个任务
    }
  });
}

// 以下代码为检测需要，请勿删除
try {
  module.exports = concurrencyLimit;
} catch (error) {}
